Skip to content

Conversation

chenyukang
Copy link
Member

Fixes #104884

@rustbot
Copy link
Collaborator

rustbot commented Nov 25, 2022

r? @petrochenkov

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 25, 2022
@chenyukang
Copy link
Member Author

I verified the change fixed this issue with serde, but I'm struggling to construct a minimal case without serde.

Appreciate if anyone could help me on this.

@petrochenkov
Copy link
Contributor

r? rust-lang/diagnostics
Skipping suggestions for macro code is relevant for pretty much all reported diagnostics.
There's probably some centralized way to do this.

@rustbot rustbot assigned TaKO8Ki and unassigned petrochenkov Nov 26, 2022
@petrochenkov
Copy link
Contributor

I'm struggling to construct a minimal case without serde.

See src/test/ui/proc-macro for examples of using proc macros in the test suite.

@TaKO8Ki
Copy link
Member

TaKO8Ki commented Nov 28, 2022

Thank you for your contribution. I found a mcve.

Given the following code as a MCVE:

src/test/ui/proc-macro/add-trait-impl.rs

// aux-build:add-trait-impl.rs

use std::collections::BinaryHeap;

#[macro_use]
extern crate add_trait_impl;

#[derive(PartialEq, Eq, PartialOrd, Ord)]
struct PriorityQueueEntry<T> {
    value: T,
}

#[derive(PartialOrd, AddImpl)]
struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>);

fn main() {}

src/test/ui/proc-macro/auxiliary/add-trait-impl.rs

// force-host
// no-prefer-dynamic

#![crate_type = "proc-macro"]

extern crate proc_macro;

use proc_macro::TokenStream;

#[proc_macro_derive(AddImpl)]

pub fn derive(input: TokenStream) -> TokenStream {
    "use std::cmp::Ordering;

    impl<T> Ord for PriorityQueue<T> {
        fn cmp(&self, other: &Self) -> Ordering {
            self.0.cmp(&self.height)
        }
    }
    "
    .parse()
    .unwrap()
}

Current output is:

error[E0277]: can't compare `PriorityQueue<T>` with `PriorityQueue<T>`
  --> /Users/maeda.takayuki/GitHub/rust/rust/src/test/ui/proc-macro/add-trait-impl.rs:13:10
   |
LL | #[derive(PartialOrd, AddImpl)]
   |          ^^^^^^^^^^ no implementation for `PriorityQueue<T> == PriorityQueue<T>`
   |
   = help: the trait `PartialEq` is not implemented for `PriorityQueue<T>`
note: required by a bound in `PartialOrd`
  --> /Users/maeda.takayuki/GitHub/rust/rust/library/core/src/cmp.rs:1083:43
   |
LL | pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
   |                                           ^^^^^^^^^^^^^^ required by this bound in `PartialOrd`
   = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `PriorityQueue<T>: Eq` is not satisfied
  --> /Users/maeda.takayuki/GitHub/rust/rust/src/test/ui/proc-macro/add-trait-impl.rs:13:22
   |
LL | #[derive(PartialOrd, AddImpl)]
   |                      ^^^^^^^ the trait `Eq` is not implemented for `PriorityQueue<T>`
   |
note: required by a bound in `Ord`
  --> /Users/maeda.takayuki/GitHub/rust/rust/library/core/src/cmp.rs:765:16
   |
LL | pub trait Ord: Eq + PartialOrd<Self> {
   |                ^^ required by this bound in `Ord`
   = note: this error originates in the derive macro `AddImpl` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: can't compare `T` with `T`
  --> /Users/maeda.takayuki/GitHub/rust/rust/src/test/ui/proc-macro/add-trait-impl.rs:13:22
   |
LL | #[derive(PartialOrd, AddImpl)]
   |                      ^^^^^^^ no implementation for `T < T` and `T > T`
   |
note: required for `PriorityQueue<T>` to implement `PartialOrd`
  --> /Users/maeda.takayuki/GitHub/rust/rust/src/test/ui/proc-macro/add-trait-impl.rs:13:10
   |
LL | #[derive(PartialOrd, AddImpl)]
   |          ^^^^^^^^^^
note: required by a bound in `Ord`
  --> /Users/maeda.takayuki/GitHub/rust/rust/library/core/src/cmp.rs:765:21
   |
LL | pub trait Ord: Eq + PartialOrd<Self> {
   |                     ^^^^^^^^^^^^^^^^ required by this bound in `Ord`
   = note: this error originates in the derive macro `AddImpl` which comes from the expansion of the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
   |
LL | #[derive(PartialOrd, AddImpl: std::cmp::PartialOrd)]
   |                             ++++++++++++++++++++++

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0277`.

The suggestion is a little bit different from what the issue says, but it might help you.

@chenyukang
Copy link
Member Author

Thanks very much! @TaKO8Ki
This code could be MCVE for the issue, seems serde does something different,
but the wrong suggestion comes with the same codepath, and this PR fixes it.
I will add it as unit testcase.

@TaKO8Ki TaKO8Ki added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 28, 2022
@chenyukang chenyukang force-pushed the yukang/fix-104884-serde branch from dc1e083 to 7d2346e Compare November 28, 2022 12:23
…unsatisfied trait bounds in derive macro code
@TaKO8Ki
Copy link
Member

TaKO8Ki commented Nov 30, 2022

After reviewing your code, I thought that rustc should suggest like the following in this case. What do you think about? That is because skipping suggestions for macro code is just a quick fix.

Given the following code:

use std::collections::BinaryHeap;

#[derive(PartialEq, Eq, PartialOrd, Ord, serde::Serialize)]
struct PriorityQueueEntry<T> {
    value: T,
}

#[derive(serde::Serialize)]
struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>);

Rustc should suggest like:

error[E0277]: the trait bound `T: Ord` is not satisfied
   --> src/main.rs:8:10
    |
8   | #[derive(serde::Serialize)]
    |          ^^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `T`
9   | struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>);
    |                         --------------------------------- required by a bound introduced by this call
    |
note: required for `PriorityQueueEntry<T>` to implement `Ord`
   --> src/main.rs:3:37
    |
3   | #[derive(PartialEq, Eq, PartialOrd, Ord, serde::Serialize)]
    |                                     ^^^
    = note: required for `BinaryHeap<PriorityQueueEntry<T>>` to implement `Serialize`
note: required by a bound in `serialize_newtype_struct`
   --> /Users/maeda.takayuki/.cargo/registry/src/mygithub.libinneed.workers.dev-1ecc6299db9ec823/serde-1.0.148/src/ser/mod.rs:904:12
    |
904 |         T: Serialize;
    |            ^^^^^^^^^ required by this bound in `serialize_newtype_struct`
    = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
- help: consider further restricting type parameter `T`
-     |
- 8   | #[derive(serde::Serialize, T: std::cmp::Ord)]
-     |                          ++++++++++++++++++
+ help: consider restricting type parameter `T`
+   |
+ 9 | struct PriorityQueue<T: std::cmp::Ord>(BinaryHeap<PriorityQueueEntry<T>>);
+   |                       +++++++++++++++

@chenyukang
Copy link
Member Author

Yes, you're right!
seems the span for suggestion is wrong.
Let me think how to fix it.

@chenyukang
Copy link
Member Author

@TaKO8Ki I'm still learning this part of code,
if you already have a fix please create a new PR, I will close this one😊

@chenyukang
Copy link
Member Author

I guess bounds_span_for_suggestions does not handle well for derive scenario.

@chenyukang chenyukang force-pushed the yukang/fix-104884-serde branch from 7d2346e to 3980945 Compare November 30, 2022 05:51
@TaKO8Ki
Copy link
Member

TaKO8Ki commented Nov 30, 2022

@bors r+ rollup

@bors
Copy link
Collaborator

bors commented Nov 30, 2022

📌 Commit 3980945 has been approved by TaKO8Ki

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Nov 30, 2022
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Nov 30, 2022
…, r=TaKO8Ki

Avoid Invalid code suggested when encountering unsatisfied trait bounds in derive macro code

Fixes rust-lang#104884
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 1, 2022
…iaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang#103065 (rustdoc-json: Document and Test that args can be patterns.)
 - rust-lang#104865 (Don't overwrite local changes when updating submodules)
 - rust-lang#104895 (Avoid Invalid code suggested when encountering unsatisfied trait bounds in derive macro code)
 - rust-lang#105063 (Rustdoc Json Tests: Don't assume that core::fmt::Debug will always have one item.)
 - rust-lang#105064 (rustdoc: add comment to confusing CSS `main { min-width: 0 }`)
 - rust-lang#105074 (Add Nicholas Bishop to `.mailmap`)
 - rust-lang#105081 (Add a regression test for rust-lang#104322)
 - rust-lang#105086 (rustdoc: clean up sidebar link CSS)
 - rust-lang#105091 (add Tshepang Mbambo to .mailmap)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit eabc072 into rust-lang:master Dec 1, 2022
@rustbot rustbot added this to the 1.67.0 milestone Dec 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Invalid code suggested when encountering unsatisfied trait bounds in derive macro code
5 participants